package com.ironman.analyze.core.compute.entity;

import cn.hutool.core.util.NumberUtil;
import com.ironman.common.util.AccuracyUtil;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;

@Data
@Builder
public class TrainingReport implements Training {

    private String mHmId;

    private String mHmName;

    private List<String> sportsman;

    private TrainingSpeedReport speedReport;

    private TrainingPostureReport postureReport;

    private Map<String, Map<String, Map<String, Long>>> rolReport;

    @Data
    @NoArgsConstructor
    public static class TrainingSpeedReport {

        /**
         * 平均风速
         */
        private Double avgWindSpeed;

        /**
         * 平均VMG
         */
        private Double avgVmg;

        /**
         * VMG标准差
         */
        private Double stdVmg;

        /**
         * 平均船速
         */
        private Double avgSpeed;

        /**
         * 船速标准差
         */
        private Double stdSpeed;

        /**
         * 平均角度
         */
        private Double avgAngle;

        /**
         * 角度标准差
         */
        private Double stdAngle;

        /**
         * 航行时间
         */
        private long trainingTime;

        public TrainingSpeedReport(Double avgWindSpeed, Double avgVmg, Double stdVmg, Double avgSpeed, Double stdSpeed, Double avgAngle, Double stdAngle, long trainingTime) {
            this.avgWindSpeed = AccuracyUtil.halfUpSpeedDouble(avgWindSpeed);

            this.avgVmg = AccuracyUtil.halfUpSpeedDouble(avgVmg);
            this.stdVmg = AccuracyUtil.halfUpSpeedDouble(stdVmg);

            this.avgSpeed = AccuracyUtil.halfUpSpeedDouble(avgSpeed);
            this.stdSpeed = AccuracyUtil.halfUpSpeedDouble(stdSpeed);

            this.avgAngle = AccuracyUtil.halfUpAngeDouble(avgAngle, 2);
            this.stdAngle = AccuracyUtil.halfUpAngeDouble(stdAngle, 2);

            this.trainingTime = trainingTime;
        }
    }

    @Data
    @NoArgsConstructor
    public static class TrainingPostureReport {

        /**
         * 平均平衡倾角值
         */
        private Double avgBalance;

        /**
         * 平衡标准差
         */
        private Double stdBalance;

        /**
         * 平衡次数
         */
        private int balanceCount;

        /**
         * 平衡次数%
         */
        private double balanceCountPer;

        /**
         * 平均反扣倾角值
         */
        private Double avgReverse;

        /**
         * 反扣标准差
         */
        private Double stdReverse;

        /**
         * 反扣次数
         */
        private int reverseCount;

        /**
         * 反扣次数%
         */
        private double reverseCountPer;

        /**
         * 平均倾斜倾角值
         */
        private Double avgTilt;

        /**
         * 倾斜标准差
         */
        private Double stdTilt;

        /**
         * 倾斜次数
         */
        private int tiltCount;

        /**
         * 倾斜次数%
         */
        private double tiltCountPer;

        /**
         * 航行时间
         */
        private long trainingTime;

        public TrainingPostureReport(Double avgBalance, Double stdBalance, int balanceCount, Double avgReverse, Double stdReverse, int reverseCount, Double avgTilt, Double stdTilt, int tiltCount) {
            this.avgBalance = AccuracyUtil.halfUpAngeDouble(avgBalance, 1);
            this.stdBalance = AccuracyUtil.halfUpAngeDouble(stdBalance, 1);
            this.balanceCount = balanceCount;

            this.avgReverse = AccuracyUtil.halfUpAngeDouble(avgReverse, 1);
            this.stdReverse = AccuracyUtil.halfUpAngeDouble(stdReverse, 1);
            this.reverseCount = reverseCount;

            this.avgTilt = AccuracyUtil.halfUpAngeDouble(avgTilt, 1);
            this.stdTilt = AccuracyUtil.halfUpAngeDouble(stdTilt, 1);
            this.tiltCount = tiltCount;

            this.trainingTime = balanceCount + reverseCount + tiltCount;
            this.balanceCountPer = this.trainingTime == 0 ? 0.0 : NumberUtil.div(balanceCount * 100, this.trainingTime, 1);
            this.reverseCountPer = this.trainingTime == 0 ? 0.0 : NumberUtil.div(reverseCount * 100, this.trainingTime, 1);
            this.tiltCountPer = this.trainingTime == 0 ? 0.0 : NumberUtil.div(tiltCount * 100, this.trainingTime, 1);
        }
    }


}
